import { getConfig } from '../config/index'

/**
 * 轻量级代理租约管理（进程内内存实现）
 * - 粘性：同一 key 在 TTL 内保留租约窗口
 * - 并发：按配置 proxy.max_concurrent_per_ip 控制同一 key 的并发租约数
 * - 释放：流程结束调用 release 归还并尝试清理过期项
 */
// legacy static ProxyLease removed in favor of instance-based implementation below

/**
 * 租约项
 * - 包含租约到期时间
 */
/* legacy placeholder removed: using instance-based implementation below */

/**
 * 代理租约管理器
 * - 管理代理租约的获取和释放
 * - 支持租约的自动清理
 */
class ProxyLeaseImpl {
  private store: Map<string, { active: number, until: number }> = new Map()

  private getMaxPerKey(): number {
    try {
      const config = getConfig()
      const maxConcurrent = config.proxy.max_concurrent_per_ip
      const n = Number(maxConcurrent)
      return Number.isFinite(n) && n > 0 ? Math.floor(n) : 1
    }
    catch { return 1 }
  }

  private sweep(): void {
    const now = Date.now()
    for (const [k, v] of this.store.entries()) {
      if (!v)
        this.store.delete(k)
      else if (v.until <= now && (v.active || 0) <= 0)
        this.store.delete(k)
    }
  }

  public lease(server: string, ttlMs: number): boolean {
    this.sweep()
    const now = Date.now()
    const key = String(server || '')
    if (!key)
      return false
    const maxPerKey = this.getMaxPerKey()
    const rec = this.store.get(key) || { active: 0, until: now + Math.max(1000, Math.floor(ttlMs)) }
    if (rec.active >= maxPerKey)
      return false
    rec.active += 1
    rec.until = Math.max(rec.until, now + Math.max(1000, Math.floor(ttlMs)))
    this.store.set(key, rec)
    return true
  }

  public release(server: string): void {
    try {
      const key = String(server || '')
      const rec = this.store.get(key)
      if (!rec)
        return
      rec.active = Math.max(0, (rec.active || 0) - 1)
      if (rec.active === 0 && rec.until <= Date.now())
        this.store.delete(key)
      else
        this.store.set(key, rec)
    }
    catch {}
  }

  public isLeased(server: string): boolean {
    this.sweep()
    const it = this.store.get(String(server || ''))
    return !!(it && it.until > Date.now() && (it.active || 0) > 0)
  }

  public snapshot(): Array<{ key: string, active: number, ttlMsLeft: number }> {
    const now = Date.now()
    const out: Array<{ key: string, active: number, ttlMsLeft: number }> = []
    for (const [k, v] of this.store.entries()) {
      const ttlLeft = Math.max(0, v.until - now)
      if ((v.active || 0) <= 0 && ttlLeft === 0)
        continue
      out.push({ key: k, active: v.active || 0, ttlMsLeft: ttlLeft })
    }
    return out
  }
}

export const ProxyLease = new ProxyLeaseImpl()
